## R Code for Replication: 
# Online Appendix
# Electoral Dis-connection: The Limits of Re-Election in Contexts of Weak Accountability
# Julie Anne Weaver
# Journal of Politics


################
############### Appendix A - RDD Robustness Checks
################

# dataset name: RDD.data

################
################ Figure A.1: RDD Bandwidth Sensitivity Check
################

library(rddtools)

## create the data for use with rddtools:
rdd.data.rddtools <- rdd_data(y=RDD.data$won, x=RDD.data$margin.voteshare.prev, cutpoint=0, 
                              data=RDD.data)

### run the rdd regression:
reg.rddtools <- rdd_reg_np(rdd_object=rdd.data.rddtools, covariates = NULL, bw =  0.097,
                           slope = "separate", inference = "np")

# check estimates are the same as with rddrobust (main text)
summary(reg.rddtools) 
## RDD estimate: -0.241
# p value <.001

## save the data as a data.frame to plot by hand to customize
rdd.sensitivity <- plotSensi(rdd_regobject=reg.rddtools, by = 0.001, 
                             level = 0.95, output="data",
                             device = "base")

## plot
plot(x=rdd.sensitivity$bw, y=rdd.sensitivity$LATE, pch=20, ylim=c(-.3, .3),
     ylab="Estimates and 95% CIs", xlab="Bandwidth", main="")
points(x=rdd.sensitivity$bw, y=rdd.sensitivity$CI_low, pch=96)
points(x=rdd.sensitivity$bw, y=rdd.sensitivity$CI_high, pch=96)
abline(h=0)

################
################ Figure A.2: McCrary Density Test
################

library(rddensity)

rddens <- rddensity(X=RDD.data$margin.voteshare.prev, c = 0, p = 2, q = 0, kernel = "triangular", 
                    h = .097, all = FALSE)

rdplotdensity <- rdplotdensity(rddens, X=RDD.data$margin.voteshare.prev, plotRange = c(-1, 1), 
                               plotN = 50,
                               type="points", pcol="black", lcol="black", 
                               xlabel="Voteshare Margin in Previous Election") 

#### customize plot with ggplot2 to add vertical line at 0

library(ggplot2)

rdplotdensity$Estplot + geom_vline(xintercept=0, size=.1)


################ 
################ Figure A.3: Incumbency Disadvantage in Peruvian Mayoral Elections, 2006
################

library(rdrobust)

rdd.2006 <- rdrobust(y=RDD.data$won[RDD.data$year==2006], 
                     x=RDD.data$margin.voteshare.prev[RDD.data$year==2006], 
                     cluster=RDD.data$UbigeoJNE[RDD.data$year==2006])
summary(rdd.2006)
# estimate: -.124
# p value <.001

rdplot(y=RDD.data$won[RDD.data$year==2006], 
       x=RDD.data$margin.voteshare.prev[RDD.data$year==2006],
       kernel="tri",
       x.label="Voteshare Margin in Previous Election", 
       y.label="Likelihood of Winning Current Election", 
       title="", h=.081,
       binselect="es")


################ 
################ Figure A.4: Incumbency Disadvantage in Peruvian Mayoral Elections, 2010
################

rdd.2010 <- rdrobust(y=RDD.data$won[RDD.data$year==2010], 
                     x=RDD.data$margin.voteshare.prev[RDD.data$year==2010], 
                     cluster=RDD.data$UbigeoJNE[RDD.data$year==2010])

summary(rdd.2010)
# estimate: -0.241
# p value <.001

rdplot(y=RDD.data$won[RDD.data$year==2010], 
       x=RDD.data$margin.voteshare.prev[RDD.data$year==2010],
       kernel="tri",
       x.label="Voteshare Margin in Previous Election", 
       y.label="Likelihood of Winning Current Election",
       title="", h=0.106,
       binselect="es")

################ 
################ Figure A.5: Incumbency Disadvantage in Peruvian Mayoral Elections, 2014
################

rdd.2014 <- rdrobust(y=RDD.data$won[RDD.data$year==2014], 
                     x=RDD.data$margin.voteshare.prev[RDD.data$year==2014], 
                     cluster=RDD.data$UbigeoJNE[RDD.data$year==2014])

summary(rdd.2014)
# estimate: -0.344 
# p value <.001

rdplot(y=RDD.data$won[RDD.data$year==2014], 
       x=RDD.data$margin.voteshare.prev[RDD.data$year==2014],
       kernel="tri",
       x.label="Voteshare Margin in Previous Election", 
       y.label="Likelihood of Winning Current Election",
       title="", h=0.102,
       binselect="es")

################ 
################ Figure A.6: Incumbency Disadvantage Conditional on Incumbent Re-Running, 2006-2014
################ 

### RDD only including races in which the incumbent ran for re-election 

rdd.incumbent.ran.district <- rdrobust(y=RDD.data$won[RDD.data$incumbent.ran.district==1], 
                                       x=RDD.data$margin.voteshare.prev[RDD.data$incumbent.ran.district==1], 
                                       cluster=RDD.data$UbigeoJNE[RDD.data$incumbent.ran.district==1])
summary(rdd.incumbent.ran.district)
## RDD esimate: -.127
# p value <.001

# plot
rdplot(y=RDD.data$won[RDD.data$incumbent.ran.district==1], 
       x=RDD.data$margin.voteshare.prev[RDD.data$incumbent.ran.district==1], 
       kernel="tri",
       x.label="Voteshare Margin in Previous Election", y.label="Likelihood of Winning Current Election",
       title="", h=.093)



################ 
################ Figure A.7: Impact of Previous Voteshare on Decision to Run, 2006-2014
################ 

### RDD: outcome = whether the candidate ran  
rdd.decision.to.run <- rdrobust(y=RDD.data$ran, x=RDD.data$margin.voteshare.prev, 
                                cluster=RDD.data$UbigeoJNE)

summary(rdd.decision.to.run)
## RDD estimate: -0.179
# p value <.001

### plot
rdplot(y=RDD.data$ran, x=RDD.data$margin.voteshare.prev, kernel="tri",
       x.label="Voteshare Margin in Previous Election", y.label="Likelihood of Running in Current Election",
       title="", h=.103)

################ 
################ Appendix A1: Randomization Inference
################ 


library(rdlocrand)

## using only 2014 data which has 5 candidate characteristics available: 

rdwinselect(R=RDD.data$margin.voteshare.prev[RDD.data$year==2014], 
            X=RDD.data[RDD.data$year==2014, c("female", "Age", "Years_Residing", "educ",
                                              "Tipo.Organizacion.Politica.prev.numeric")],
            seed=02138)

# $window
# [1] -0.00137  0.00137

## how many observations fall in that window?
length(RDD.data$won[!is.na(RDD.data$margin.voteshare.prev) & 
                      RDD.data$year==2014 &
                      RDD.data$margin.voteshare.prev>-0.00137 & 
                      RDD.data$margin.voteshare.prev<0.00137]) # 34

### running the RDD on the 2014 data within that window

rdrandinf(Y=RDD.data$won[RDD.data$year==2014], 
          R=RDD.data$margin.voteshare.prev[RDD.data$year==2014], 
          wl=-0.00137,wr=0.00137, seed=02138)

# Statistic            T              P>|T|          P>|T|     Power vs d = 0.261

# Diff. in means       -0.364         00.032          0.031     0.342


#### running the RDD on the full dataset (all 3 elections) with the window estimated from 2014 data:

rdrandinf(Y=RDD.data$won, R=RDD.data$margin.voteshare.prev, wl=-0.00137, wr=0.00137,
          seed=02138)

## Statistic            T              P>|T|          P>|T|     Power vs d = 0.25

# Diff. in means       -0.213         0.026          0.023     0.762



######## selecting the window using the only 2 covariates available across all elections (gender and party type)

rdwinselect(R=RDD.data$margin.voteshare.prev, X=RDD.data[, c("female", "Tipo.Organizacion.Politica.prev.numeric")],
            seed=02138) 

## recommended window:
#$window
#[1] -0.00078  0.00078

## how many observations fall in this window?

length(RDD.data$margin.voteshare.prev[!is.na(RDD.data$margin.voteshare.prev) & 
                                        RDD.data$margin.voteshare.prev>-0.00078 & 
                                        RDD.data$margin.voteshare.prev<0.00078]) # 57 obs

57/nrow(RDD.data) # 0.001640902 or less than 1%

## run the RDD using this window: 

rdrandinf(Y=RDD.data$won, R=RDD.data$margin.voteshare.prev, wl=-0.00078,wr=0.00078, seed=02138)


# Statistic            T              P>|T|          P>|T|     Power vs d = 0.264

# Diff. in means       -0.306         0.118          0.102     0.292





################
################ APPENDIX F - ADDITIONAL INFORMATION ON THE CONJOINT EXPERIMENT
################

## descriptive stats from original survey
# dataset used: survey.data

################
################ Table F.1: How Many Mayors in this Municipality...
################

## answer options
# 1 = all
# 2 = majority
# 3 = half
# 4 = some
# 5 = none
# -99 = don't know
# -97 = no response

# Question: How many of the past mayors in this municipality have implemented public works projects? 

prop.table(table(survey.data$mayors.pw))
#  -99        -97          1          2          3          4          5 
# 0.04806786 0.01979265 0.07917059 0.20263902 0.16682375 0.46936852 0.01413761 


# Question: How many of the past mayors in this municipality have provided residents with individual financial help when they have asked for it for a family or health emergency?

prop.table(table(survey.data$mayors.finaid))
#   -99        -97          1          2          3          4          5 
# 0.12629595 0.02262017 0.06597549 0.09990575 0.10179076 0.39302545 0.19038643 

################
################ Table F.2: In the Last Mayoral Election in October 2014, How Many Candidates gave gifts as part of their campaign?
################

## answer options
# 1 = all
# 2 = majority
# 3 = half
# 4 = some
# 5 = none
# -99 = don't know
# -97 = no response

prop.table(table(survey.data$candidates.gifts))
#     -99        -97          1          2          3          4          5 
# 0.07822809 0.03016023 0.26861451 0.27898209 0.09048068 0.19509896 0.05843544 



################
################ APPENDIX G - CONJOINT ROBUSTNESS CHECKS 
################

################ 
################ Appendix Figure G.1: Conjoint Results Conditional on Task Number
################

# dataset used:  conjoint.data

library("cjoint")

# Note: Code in lines 314-358 is repeated from R script main text

## set the baseline levels for each attribute:

baselines <- list()
baselines$feat.gender <- "male"
baselines$feat.incumbent <- "Challenger"         
baselines$feat.soc.orgs <- "No"
baselines$feat.village <- "Village 2 hours away"
baselines$feat.work <- "Farmer"
baselines$feat.lang <- "Spanish"
baselines$feat.dynasty <- "Uncle was mayor"
baselines$feat.gifts <- "Never gives gifts at campaign events"

############### setting the weights in cjoint
# i.e. because not every attribute has an equal probability of appearing to respondents

### set attribute levels:
attribute_list <- list()
attribute_list[["feat.gender"]] <-c("female", "male")
attribute_list[["feat.incumbent"]] <-c("Incumbent - no performance info", "Incumbent - good performance - public works",
                                       "Incumbent - good performance - fin aid", "Incumbent - bad performance - fin aid",      
                                       "Incumbent - bad performance - public works", "Challenger")
attribute_list[["feat.soc.orgs"]] <-c("No", "Yes")
attribute_list[["feat.village"]] <-c("Village 2 hours away", "Same village")
attribute_list[["feat.work"]] <-c("Business owner", "Farmer")
attribute_list[["feat.lang"]] <-c("Spanish", "Quechua")
attribute_list[["feat.dynasty"]] <-c("First in family to run", "Uncle was mayor")
attribute_list[["feat.gifts"]] <-c("Gives gifts at campaign events", "Never gives gifts at campaign events")

###### set the probability of each attribute value being randomly generated

marginal_weights <- list() # Uniform for all except gender and incumbency - i.e. probability of each value within the trait is equal
marginal_weights[["feat.gender"]] <- c(1/3, 2/3) # female has only 1/3 prob 
marginal_weights[["feat.incumbent"]] <- c(1/10, 1/10, 1/10, 1/10, 1/10, 1/2) # challenger has 50% prob, all others 10%
### all the other attributes have 50% chance of being selected (always only 2 attribute levels with equal probability)
marginal_weights[["feat.soc.orgs"]] <-c(1/2, 1/2)
marginal_weights[["feat.village"]] <- c(1/2, 1/2)
marginal_weights[["feat.work"]] <- c(1/2, 1/2)
marginal_weights[["feat.lang"]] <- c(1/2, 1/2)
marginal_weights[["feat.dynasty"]] <- c(1/2, 1/2)
marginal_weights[["feat.gifts"]] <- c(1/2, 1/2)

### use makeDesign to set the weights

conj.design.reweight <- makeDesign(type="constraints", attribute.levels=attribute_list,
                                   level.probs=marginal_weights)

## NOTE: start of new code specific to Figure G1

amce1.check1 <- amce(outcome_votechoice_binary ~ `Task Number`:feat.gender + `Task Number`:feat.incumbent          
                     + `Task Number`:feat.soc.orgs + `Task Number`:feat.village + `Task Number`:feat.work                
                     + `Task Number`:feat.lang  + `Task Number`:feat.dynasty + `Task Number`:feat.gifts, data=conjoint.data,
                     respondent.varying=c("`Task Number`"),
                     cluster=TRUE, respondent.id="respondentID", design=conj.design.reweight,
                     baselines=baselines)

plot(amce1.check1, xlab="Change in Probability of Voting for a Candidate for Mayor",
     breaks=c(-.2, 0, .2), labels=c("-.2","0",".2"), text.size=10,
     label.baseline = TRUE,  plot.display="interaction",
     attribute.names=c("Political Dynasty", "Gender", "Gifts in Campaign",
                       "Incumbency Status", "Ethnicity/First Language",
                       "Social Organizations", "Village", "Work/Wealth"))   


################ 
################ Appendix Figure G.2: Conjoint Results Conditional on Profile Order
################ 

amce1.check2 <- amce(outcome_votechoice_binary ~ `First Profile`:feat.gender + `First Profile`:feat.incumbent          
                     + `First Profile`:feat.soc.orgs + `First Profile`:feat.village + `First Profile`:feat.work                
                     + `First Profile`:feat.lang  + `First Profile`:feat.dynasty + `First Profile`:feat.gifts, data=conjoint.data,
                     respondent.varying=c("`First Profile`"),
                     cluster=TRUE, respondent.id="respondentID", design=conj.design.reweight,
                     baselines=baselines)

plot(amce1.check2, xlab="Change in Probability of Voting for a Candidate for Mayor",
     breaks=c(-.2, 0, .2), labels=c("-.2","0",".2"), text.size=10,
     label.baseline = TRUE, plot.display="interaction", 
     attribute.names=c("Political Dynasty", "Gender", "Gifts in Campaign",
                       "Incumbency Status", "Ethnicity/First Language",
                       "Social Organizations", "Village", "Work/Wealth"))   




################ 
################ Table G.1: Randomization Check: Frequency of Candidate Attributes
################ 

## check frequency with which each candidate attribute appeared to respondents:

prop.table(table(conjoint.data$feat.incumbent))
prop.table(table(conjoint.data$feat.soc.orgs))
prop.table(table(conjoint.data$feat.village))
prop.table(table(conjoint.data$feat.work))
prop.table(table(conjoint.data$feat.lang))
prop.table(table(conjoint.data$feat.dynasty))
prop.table(table(conjoint.data$feat.gifts))
prop.table(table(conjoint.data$feat.gender))


################ 
################ Appendix Table G.2: Randomization Check: Candidate Attributes and Respondent Characteristics
################ 

## intuition: do profiles vary randomly across types of respondents?
## did female respondents see certain candidate attributes more than male respondents?  

###### run one regression with all candidate traits on each of the 5 respondent variables

check.rand.gender <-  lm(gender.binary ~ feat.dynasty + feat.gender + feat.gifts
                         + feat.incumbent + feat.lang + feat.soc.orgs + feat.village + feat.work, 
                         data=conjoint.data)

check.rand.educ <-  lm(educ_noNA ~ feat.dynasty + feat.gender + feat.gifts
                       + feat.incumbent + feat.lang + feat.soc.orgs + feat.village + feat.work, 
                       data=conjoint.data)

check.rand.age <-  lm(age.category.numeric ~ feat.dynasty + feat.gender + feat.gifts
                      + feat.incumbent + feat.lang + feat.soc.orgs + feat.village + feat.work, 
                      data=conjoint.data)

check.rand.income <-  lm(income.quantile ~ feat.dynasty + feat.gender + feat.gifts
                         + feat.incumbent + feat.lang + feat.soc.orgs + feat.village + feat.work, 
                         data=conjoint.data)

check.rand.quechua <-  lm(idioma.materno.quechua ~ feat.dynasty + feat.gender + feat.gifts
                          + feat.incumbent + feat.lang + feat.soc.orgs + feat.village + feat.work, 
                          data=conjoint.data)

## export results 
library(stargazer)
stargazer(check.rand.gender, check.rand.educ, check.rand.age, check.rand.income, check.rand.quechua)



################
################ Appendix Table H.1: RDD and Incumbent Re-election: Political Competition and Recalls
################

## dataset: RDD.data.heterogtxt

## each case is an OLS regression 
## municipal-level clustered standard errors using cluster.vcov()

library(multiwayvcov)
library(lmtest)

### variance of the precinct voteshare across all precincts in the district

reg.alt.votesharevar <- lm(won ~ won.prev*margin.voteshare.prev*var.party.district.prev.norm,
                           data=RDD.data.heterogtxt)

coeftest(reg.alt.votesharevar, cluster.vcov(reg.alt.votesharevar, RDD.data.heterogtxt$UbigeoJNE))


### Effective Number of Political Parties (previous election)

reg.alt.enp <- lm(won ~ won.prev*margin.voteshare.prev*enp.prev.norm,
                  data=RDD.data.heterogtxt)

coeftest(reg.alt.enp, cluster.vcov(reg.alt.enp, RDD.data.heterogtxt$UbigeoJNE))


### Recall kit requested

reg.alt.recall.req <- lm(won ~ won.prev*margin.voteshare.prev*recall.kit.requested.norm,
                         data=RDD.data.heterogtxt)

coeftest(reg.alt.recall.req, cluster.vcov(reg.alt.recall.req, RDD.data.heterogtxt$UbigeoJNE))


### Recall vote held

reg.alt.recall.held <- lm(won ~ won.prev*margin.voteshare.prev*recall.vote.held.norm,
                          data=RDD.data.heterogtxt)

coeftest(reg.alt.recall.held, cluster.vcov(reg.alt.recall.held, RDD.data.heterogtxt$UbigeoJNE))


### Recall vote held (previous election)

reg.alt.recall.held.prev <- lm(won ~ won.prev*margin.voteshare.prev*recall.vote.held.prev.norm,
                               data=RDD.data.heterogtxt)

coeftest(reg.alt.recall.held.prev, cluster.vcov(reg.alt.recall.held.prev, RDD.data.heterogtxt$UbigeoJNE))


################
################ Appendix Table H.2: RDD and Incumbent Re-election: Candidate Characteristics
################

### female
reg.female <- lm(won ~ won.prev*margin.voteshare.prev*Sexo.female.norm,
                 data=RDD.data.heterogtxt)

coeftest(reg.female, cluster.vcov(reg.female, RDD.data.heterogtxt$UbigeoJNE))


### age
reg.age <- lm(won ~ won.prev*margin.voteshare.prev*Age.norm,
              data=RDD.data.heterogtxt)

coeftest(reg.age, cluster.vcov(reg.age, RDD.data.heterogtxt$UbigeoJNE))


### Post-secondary education
reg.educ <- lm(won ~ won.prev*margin.voteshare.prev*educ.post.2ndary.norm,
               data=RDD.data.heterogtxt)

coeftest(reg.educ, cluster.vcov(reg.educ, RDD.data.heterogtxt$UbigeoJNE))

### Penal or Civil charges
reg.charges <- lm(won ~ won.prev*margin.voteshare.prev*Penal_or_Civil_charges.norm,
                  data=RDD.data.heterogtxt)

coeftest(reg.charges, cluster.vcov(reg.charges, RDD.data.heterogtxt$UbigeoJNE))

### Years residing in the district
reg.years <- lm(won ~ won.prev*margin.voteshare.prev*Years_Residing.norm,
                data=RDD.data.heterogtxt)

coeftest(reg.years, cluster.vcov(reg.years, RDD.data.heterogtxt$UbigeoJNE))


### previously elected to any office
reg.prevelected <- lm(won ~ won.prev*margin.voteshare.prev*Previously_elected.norm,
                      data=RDD.data.heterogtxt)

coeftest(reg.prevelected, cluster.vcov(reg.prevelected, RDD.data.heterogtxt$UbigeoJNE))

### leadership position within the party
reg.partyposition <- lm(won ~ won.prev*margin.voteshare.prev*Party_position.norm,
                        data=RDD.data.heterogtxt)

coeftest(reg.partyposition, cluster.vcov(reg.partyposition, RDD.data.heterogtxt$UbigeoJNE))

